#ifndef VIDEOMODEL_HXX
#define VIDEOMODEL_HXX

#include <QMetaType>
#include <QObject>
#include <FramePool.hxx>
#include <VideoThread.hxx>
#include <QMutex>
#include <QSettings>

class TrackedObject;
class VideoView;

enum SequenceType
{
    VIDEO_SEQUENCE=0,
    IMAGE_SEQUENCE
};

class Project;

class Sequence : public QObject
{
    Q_OBJECT
public:
    explicit Sequence(QObject *parent = nullptr);
	~Sequence();

signals:
	void timeStampUpdated();

public:
    inline void setVideoHeight(int height) { _videoHeight = height;}
    inline int getVideoHeight() { return _videoHeight;}

    inline void setVideoWidth(int width) { _videoWidth = width; }
    inline int getVideoWidth() { return _videoWidth; }

    inline void setId(int id) { _id = id; }
    inline int getId() { return _id; }

	inline void setName(std::string name) { _name = name; }
	inline std::string getName() { return _name; }

    inline void setType(SequenceType type) { _type = type; }
    inline SequenceType getType() { return _type; }

	inline void setFrameStrip(int strip) { _frameStrip = strip; }
	inline int getFrameStrip() { return _frameStrip; }

    inline FramePool* getFramePool() { return &_framePool; }
	inline FramePool* getTrackedFramePool() { return &_trackedFramePool; }

	void prepareTrackingObjects();
	void updateNextTrackedObjectId();
	void moveTrackedObjects();
	void makeSingleFrameObjects();
	void makeNegativeSampleFrame();
	inline std::vector<TrackedObject*>* getTrackingObjects() { return &_trackingObjects; }

	void seekVideoPosition(double pos);
	inline void lockSeekAction() { _seekMutex.lock(); }
	inline bool getSeekFlag() { return _seekFlag; }
	inline void setSeekFlag() { _seekFlag = false; }
	inline double getSeekPos() { return _seekPos; }
	inline void unlockSeekAction() { _seekMutex.unlock(); }

	inline void setVideoDuration(double duration) { _videoDuration = duration; emit timeStampUpdated();}
	inline void setCurrentTimestamp(double timestamp) { _currentTimeStamp = timestamp;  emit timeStampUpdated(); }
	inline void setCurrentFrameIndex(int index) { _currentFrameIndex = index; }
	inline double getVideoDuration() { return _videoDuration; }
	
	inline double getCurrentTimestamp() { return _currentTimeStamp; }
	inline int getCurrentFrameIndex() { return _currentFrameIndex; }
	inline void setFrameRate(double frate) { _frameRate = frate; }
	inline double getFrameRate() { return _frameRate; }

    inline void setFilePath(std::string path) { _filePath = path; }
    inline std::string getFilePath() { return _filePath; }

	inline void setVideoView(VideoView* view) { _view = view; }
    inline VideoView* getVideoView() { return _view; }


	inline std::vector<TrackedObject*>* getTrackedObjects() { return &_trackedObjects; }
	void desectAllTrackedObjects();
	void deleteSelectedObject();

	void startObject(int frameIndex);
	void endObject(int frameIndex);

	void mergeTrackedObjects(const std::vector<TrackedObject*>& objects);

	void updateObjectStartFrame(int objectId, int startFrame);
	void updateObjectEndFrame(int objectId, int endFrame);
    void updateObjectClass(int objectId, int classIndex);

	void rects2Objects();

	//inline const char* getCVideoFileName() const { return _videoFileName.toLatin1(); }
private:
	void forceObjectsConsistency();
	bool isObjectConsistency(TrackedObject* obj);
	bool forceOjbectConsistency(TrackedObject* obj);

private:
    FramePool _framePool;
	FramePool _trackedFramePool;

	VideoView* _view;

    int _videoWidth;
    int _videoHeight;

	double _videoDuration;
	int _currentFrameIndex;
	double _currentTimeStamp;
	double _frameRate;

	QMutex _seekMutex;
	bool _seekFlag;
	double _seekPos;

    std::string _filePath;
	std::string _name;

	std::vector<TrackedObject*> _trackedObjects;
	std::vector<TrackedObject*> _trackingObjects;

	int _nextTrackedObjectId;

    int _id;

    SequenceType _type;
	int _frameStrip;
};

Q_DECLARE_METATYPE(Sequence*)

#endif // VIDEOMODEL_HXX
